const express = require("express");
const path = require("path");
const fs = require("fs").promises;
const fsOriginal = require("fs"); // 添加原始 fs 模块用于 createWriteStream

const router = express.Router();
const { generateCodeFromData } = require("../service/codeGenerationService");

// 代码生成接口
router.post("/api/generate-code", (req, res) => {
  try {
    const { queryParams, listParams } = req.body;

    try {
      queryParamArray =
        typeof queryParams === "string"
          ? JSON.parse(queryParams)
          : queryParams || [];
      listParamArray =
        typeof listParams === "string"
          ? JSON.parse(listParams)
          : listParams || [];
    } catch (parseError) {
      console.error("Parameter parsing error:", parseError);
      return res
        .status(400)
        .json({ error: "参数格式错误: " + parseError.message });
    }

    // 渲染模板
    res.render(
      "test.ejs",
      {
        queryParams: queryParams || [],
        listParams: listParams || [],
      },
      (err, html) => {
        if (err) {
          console.error("Template rendering error:", err);
          return res.status(500).json({ error: "Failed to generate code" });
        }

        res.json({ code: html });
      }
    );
  } catch (error) {
    console.error("Code generation error:", error);
    res.status(500).json({ error: "Failed to generate code" });
  }
});

// 新增commonlist代码生成并下载接口
router.post("/api/generate-common-list-code-download", async (req, res) => {
  try {
    const { queryParams, listParams, filename } = req.body;
    await generateAndDownloadCode(req, res, {
      queryParams,
      listParams,
      filename: filename || "commonList.zip",
      templatePath: "commonList",
      dirName: "commonList",
      vueFileName: "list.vue",
    });
  } catch (error) {
    console.error("Code generation error:", error);
    res.status(500).json({ error: "Failed to generate code" });
  }
});

// 通用代码生成并下载接口
router.post("/api/generate-and-download", async (req, res) => {
  try {
    const {
      queryParams,
      listParams,
      filename,
      templatePath,
      dirName,
      vueFileName,
    } = req.body;

    // 参数验证
    if (!templatePath || !dirName || !vueFileName) {
      return res.status(400).json({ error: "缺少必要参数" });
    }

    await generateAndDownloadCode(req, res, {
      queryParams,
      listParams,
      filename: filename || `${dirName}.zip`,
      templatePath,
      dirName,
      vueFileName,
    });
  } catch (error) {
    console.error("Code generation error:", error);
    res.status(500).json({ error: "Failed to generate code" });
  }
});

// 代码预览接口 - 生成代码但不下载，而是返回文件列表和内容
router.post("/api/generate-code-preview", async (req, res) => {
  try {
    const requestData = req.body;

    // 检查参数
    if (!requestData.generationType ||!requestData.dataSourceConfig) {
      return res
        .status(400)
        .json({ error: "generationType is required" });
    }

    // 创建临时目录来存储生成的文件
    const tempDir = path.join(__dirname, "../temp", Date.now().toString());
    await fs.mkdir(tempDir, { recursive: true });

    const generatedDirs = [];

    try {
      // 生成commonList代码
      if (requestData && requestData.generationType == "list") {
        const listDir = await generateCodeFromData(
          requestData,
          "commonList",
          tempDir,
          res
        );
        generatedDirs.push({ type: "commonList", dir: listDir });
      } else if (requestData && requestData.generationType.startsWith("modal")) {
        const listDir = await generateCodeFromData(
          requestData,
          requestData.generationType,
          tempDir,
          res
        );
        generatedDirs.push({ type: "modal", dir: listDir });
      } else if (requestData && requestData.generationType === "list_detail") {
        // 如果 requestData.pageCode 是对象
        let headPageCode = requestData.pageCode;
        let listPageCode = requestData.pageCode;
        if (typeof headPageCode === 'object') {
          headPageCode = requestData.pageCode.header;
          listPageCode = requestData.pageCode.body;
        }
        // 生成列表部分代码
        const listDir = await generateCodeFromData(
          {...requestData, pageCode: headPageCode},
          "ldzh_list",
          tempDir,
          res,
          "list"
        );
        generatedDirs.push({ type: "list", dir: listDir });
        
        // 生成详情部分代码
        const detailDir = await generateCodeFromData(
          {...requestData, pageCode: listPageCode},
          "ldzh_detail",
          tempDir,
          res,
          'list/detail'
        );
        generatedDirs.push({ type: "detail", dir: detailDir});
      }
      // 生成detail代码
      else if (requestData && requestData.generationType === "detail") {
        const detailDir = await generateCodeFromData(
          requestData,
          "detail",
          tempDir,
          res
        );
        generatedDirs.push({ type: "detail", dir: detailDir });
      } 
      // 生成多页签详情代码
      else if (requestData && requestData.generationType === "multi_tab_detail") {
        const detailDir = await generateCodeFromData(
          requestData,
          "multi_tab_detail",
          tempDir,
          res,
          'detail'
        );
        generatedDirs.push({ type: "multi_tab_detail", dir: detailDir });
      }
      else {
        return res.status(400).json({ error: "缺少必要参数" });
      }

      // 读取生成的文件内容
      const fileList = [];
      const fileMap = new Map(); // 用于存储已存在的文件路径

      for (const { type, dir } of generatedDirs) {
        const dirPath = path.join(tempDir, dir);
        const files = await readDirectoryRecursive(dirPath, dir);
        
        for (const file of files) {
          const filePath = file.path;
          if (!fileMap.has(filePath)) {
            fileMap.set(filePath, file);
            fileList.push({
              ...file,
              path: `/${filePath}`,
            });
          }
        }
      }

      // 返回文件列表和内容
      res.json({
        success: true,
        files: fileList,
        rootPath: tempDir,
      });

      // 清理临时文件(延迟清理，确保客户端能获取到文件)
      setTimeout(() => {
        fs.rm(tempDir, { recursive: true }).catch((err) =>
          console.error("Failed to clean up temp files:", err)
        );
      }, 60000); // 1分钟后清理
    } catch (error) {
      console.error("Code generation error:", error);
      // 清理临时文件
      fs.rm(tempDir, { recursive: true }).catch((err) =>
        console.error("Failed to clean up temp files:", err)
      );
      throw error;
    }
  } catch (error) {
    console.error("Code generation error:", error);
    res.status(500).json({ error: "Failed to generate code" });
  }
});

// 读取文件内容的辅助函数
async function readFileContent(filePath) {
  try {
    const content = await fs.readFile(filePath, "utf-8");
    return content;
  } catch (error) {
    return `无法读取文件: ${error.message}`;
  }
}

// 递归读取目录的辅助函数
async function readDirectoryRecursive(dirPath, basePath = "") {
  const entries = await fs.readdir(dirPath, { withFileTypes: true });
  const files = [];

  for (const entry of entries) {
    const relativePath = basePath
      ? path.join(basePath, entry.name)
      : entry.name;
    const fullPath = path.join(dirPath, entry.name);

    if (entry.isDirectory()) {
      const subFiles = await readDirectoryRecursive(fullPath, relativePath);
      files.push(...subFiles);
    } else {
      const content = await readFileContent(fullPath);
      files.push({
        path: relativePath,
        name: entry.name,
        content: content,
        isBinary: isBinaryFile(entry.name),
      });
    }
  }

  return files;
}

// 判断是否为二进制文件
function isBinaryFile(filename) {
  const binaryExtensions = [
    ".png",
    ".jpg",
    ".jpeg",
    ".gif",
    ".bmp",
    ".ico",
    ".pdf",
    ".zip",
    ".exe",
  ];
  const ext = path.extname(filename).toLowerCase();
  return binaryExtensions.includes(ext);
}

/**
 * 通用代码生成并下载函数
 */
async function generateAndDownloadCode(req, res, options) {
  const {
    queryParams,
    listParams,
    filename,
    templatePath,
    dirName,
    vueFileName,
  } = options;

  let queryParamArray = [];
  let listParamArray = [];

  try {
    queryParamArray =
      typeof queryParams === "string"
        ? JSON.parse(queryParams)
        : queryParams || [];
    listParamArray =
      typeof listParams === "string"
        ? JSON.parse(listParams)
        : listParams || [];
  } catch (parseError) {
    console.error("Parameter parsing error:", parseError);
    return res
      .status(400)
      .json({ error: "参数格式错误: " + parseError.message });
  }

  // 创建临时目录来存储生成的文件
  const tempDir = path.join(__dirname, "../temp", Date.now().toString());
  await fs.mkdir(tempDir, { recursive: true });

  try {
    // 创建目录结构
    const targetDir = path.join(tempDir, dirName);
    const hooksDir = path.join(targetDir, "hooks");
    await fs.mkdir(targetDir, { recursive: true });
    await fs.mkdir(hooksDir, { recursive: true });

    // 渲染 useForms.ejs 模板
    const formsContent = await new Promise((resolve, reject) => {
      res.render(
        `${templatePath}/hooks/useForms.ejs`,
        {
          queryParams: queryParamArray,
          listParams: listParamArray,
        },
        (err, html) => {
          if (err) {
            console.error("Error rendering useForms.ejs:", err);
            reject(err);
          } else {
            resolve(html);
          }
        }
      );
    });

    // 渲染 useTables.ejs 模板 (如果存在)
    let tablesContent = "";
    try {
      tablesContent = await new Promise((resolve, reject) => {
        res.render(
          `${templatePath}/hooks/useTables.ejs`,
          {
            queryParams: queryParamArray,
            listParams: listParamArray,
          },
          (err, html) => {
            if (err) {
              // 如果模板不存在，忽略错误
              resolve("");
            } else {
              resolve(html);
            }
          }
        );
      });
    } catch (error) {
      // 忽略错误
      console.warn("useTables.ejs template not found, skipping...");
    }

    // 写入 hooks 文件
    await fs.writeFile(path.join(hooksDir, "useForms.ts"), formsContent);
    if (tablesContent) {
      await fs.writeFile(path.join(hooksDir, "useTables.ts"), tablesContent);
    }

    // 复制其他固定文件
    const originalHooksDir = path.join(
      __dirname,
      "../../codeTemplate",
      templatePath,
      "hooks"
    );
    try {
      const files = await fs.readdir(originalHooksDir);
      for (const file of files) {
        // 跳过已经生成的文件
        if (
          file === "useForms.ejs" ||
          file === "useTables.ejs" ||
          file === "useForms.ts" ||
          file === "useTables.ts"
        ) {
          continue;
        }
        const sourcePath = path.join(originalHooksDir, file);
        const destPath = path.join(hooksDir, file);
        await fs.copyFile(sourcePath, destPath);
      }
    } catch (error) {
      console.warn("Error copying hook files:", error);
    }

    // 处理Vue文件
    const vueSourcePath = path.join(
      __dirname,
      "../../codeTemplate",
      templatePath,
      vueFileName
    );
    const vueDestPath = path.join(targetDir, vueFileName);
    await fs.copyFile(vueSourcePath, vueDestPath);

    // 创建压缩包
    const archiver = require("archiver");
    const zipFilename = filename;
    const zipFilePath = path.join(tempDir, zipFilename);

    const output = fsOriginal.createWriteStream(zipFilePath);
    const archive = archiver("zip", {
      zlib: { level: 9 },
    });

    archive.pipe(output);
    archive.directory(targetDir, dirName);

    // 等待归档完成
    await new Promise((resolve, reject) => {
      output.on("close", resolve);
      archive.on("error", reject);
      archive.finalize();
    });

    // 发送压缩包给客户端
    res.setHeader("Content-Disposition", `attachment; filename="${filename}"`);
    res.setHeader("Content-Type", "application/zip");
    res.sendFile(zipFilePath, (err) => {
      // 清理临时文件
      fs.rm(tempDir, { recursive: true }).catch((err) =>
        console.error("Failed to clean up temp files:", err)
      );
    });
  } catch (error) {
    console.error("Code generation error:", error);
    // 清理临时文件
    fs.rm(tempDir, { recursive: true }).catch((err) =>
      console.error("Failed to clean up temp files:", err)
    );
    throw error; // 重新抛出错误，让调用者处理响应
  }
}

// 新增接口：支持从前端传来数据，生成commonList和detail代码
router.post("/api/generate-code-from-data", async (req, res) => {
  try {
    const requestData = req.body;

    // 检查参数
    if (!requestData.generationType || !requestData.dataSourceConfig) {
      return res
        .status(400)
        .json({ error: "generationType 和 dataSourceConfig 不能为空" });
    }

    // 创建临时目录来存储生成的文件
    const tempDir = path.join(__dirname, "../temp", Date.now().toString());
    await fs.mkdir(tempDir, { recursive: true });

    const generatedDirs = [];

    try {
      // 生成commonList代码
      if (requestData && requestData.generationType == "list") {
        const listDir = await generateCodeFromData(
          requestData,
          "commonList",
          tempDir,
          res
        );
        generatedDirs.push(listDir);
      }
      
      // 生成弹框表格代码
      else if (requestData && requestData.generationType.startsWith("modal")) {
        const modalDir = await generateCodeFromData(
          requestData,
          requestData.generationType,
          tempDir,
          res
        );
        generatedDirs.push(modalDir);
      }
      
      // 生成列表详情代码
      else if (requestData && requestData.generationType === "list_detail") {
        // 如果 requestData.pageCode 是对象
        let headPageCode = requestData.pageCode;
        let listPageCode = requestData.pageCode;
        if (typeof headPageCode === 'object') {
          headPageCode = requestData.pageCode.header;
          listPageCode = requestData.pageCode.body;
        } 
        // 生成列表部分代码
        const listDir = await generateCodeFromData(
          {...requestData, pageCode: headPageCode},
          "ldzh_list",
          tempDir,
          res,
          "list"
        );
        generatedDirs.push(listDir);
        
        // 生成详情部分代码
        const detailDir = await generateCodeFromData(
          {...requestData, pageCode: listPageCode},
          "ldzh_detail",
          tempDir,
          res,
          'list/detail'
        );
        generatedDirs.push(detailDir);
      }

       // 生成弹框表格代码
       else if (requestData && requestData.generationType.startsWith("modal")) {
        const modalDir = await generateCodeFromData(
          requestData,
          requestData.generationType,
          tempDir,
          res
        );
        generatedDirs.push(modalDir);
      } 
      
      // 生成detail代码
      else if (requestData&& requestData.generationType.startsWith("detail")) {
        const detailDir = await generateCodeFromData(
          requestData,
          "detail",
          tempDir,
          res
        );
        generatedDirs.push(detailDir);
      } 
      
      // 生成多页签详情代码
      else if (requestData && requestData.generationType === "multi_tab_detail") {
        const detailDir = await generateCodeFromData(
          requestData,
          "multi_tab_detail",
          tempDir,
          res
        );
        generatedDirs.push(detailDir);
      }
      
      else {
        return res
          .status(400)
          .json({ error: "requestData.generationType is missing or invalid" });
      }

      // 创建压缩包
      const archiver = require("archiver");
      const zipFilename = "generated-code.zip";
      const zipFilePath = path.join(tempDir, zipFilename);

      const output = fsOriginal.createWriteStream(zipFilePath);
      const archive = archiver("zip", {
        zlib: { level: 9 },
      });

      archive.pipe(output);

      // 将所有生成的目录添加到压缩包中
      for (const dir of generatedDirs) {
        const dirPath = path.join(tempDir, dir);
        archive.directory(dirPath, dir);
      }

      // 等待归档完成
      await new Promise((resolve, reject) => {
        output.on("close", resolve);
        archive.on("error", reject);
        archive.finalize();
      });

      // 发送压缩包给客户端
      res.setHeader(
        "Content-Disposition",
        `attachment; filename="${zipFilename}"`
      );
      res.setHeader("Content-Type", "application/zip");
      res.sendFile(zipFilePath, (err) => {
        // 清理临时文件
        fs.rm(tempDir, { recursive: true }).catch((err) =>
          console.error("Failed to clean up temp files:", err)
        );
      });
    } catch (error) {
      console.error("Code generation error:", error);
      // 清理临时文件
      fs.rm(tempDir, { recursive: true }).catch((err) =>
        console.error("Failed to clean up temp files:", err)
      );
      throw error;
    }
  } catch (error) {
    console.error("Code generation error:", error);
    res.status(500).json({ error: "代码生成失败: " + error.message });
  }
});

module.exports = router;
